package com.shuqi.common.utils;

import java.util.List;

import android.content.Context;
import android.text.TextUtils;

import com.shuqi.common.Constant;
import com.shuqi.controller.R;
import com.shuqi.database.dao.impl.BookCataLogDao;
import com.shuqi.database.dao.impl.BookInfoDao;
import com.shuqi.database.dao.impl.BookMarkInfoDao;
import com.shuqi.database.model.BookCataLog;
import com.shuqi.database.model.BookInfo;
import com.shuqi.database.model.BookMarkInfo;
import com.shuqi.model.BookContentModel;
import com.shuqi.model.bean.BookContentInfo;
import com.shuqi.model.bean.BookContentLineInfo;
import com.shuqi.model.parse.BookContentParserBase;
import com.shuqi.model.parse.parser.BookContentLocalAppBagParser;
import com.shuqi.model.parse.parser.BookContentLocalAppEPUBParser;
import com.shuqi.model.parse.parser.BookContentLocalAppTXTParser;
import com.shuqi.model.parse.parser.BookContentLocalAppUMDParser;
import com.shuqi.model.parse.parser.BookContentPayBookParser;

public class BookContentUtils {
    /*-------阅读页绘制状态--------*/
    /** 需要购买 */
    public static final String TYPE_NEDD_BUY = "-4";
    /** 正常阅读 */
    public static final String TYPE_HAS_READ = "1";// 底层有可正常阅读的数据和阅读页绘制正常文字都返回此标记
    /** 未登录 */
    public static final String TYPE_NO_LOGIN = "10";

    /*-----------收费书籍类型-------------*/
    /** 全本购买 */
    public static final String PAY_TYPE_BOOK = "1";
    /** 按章 */
    public static final String PAY_TYPE_CHAPTER = "2";

    /*-------阅读页获取数据状态--------*/
    /** 下载失败 */
    public static final String TYPE_DOWN_FAIL = "-1";
    /** 书籍关闭 */
    public static final String TYPE_BOOK_CLOSED = "-5";
    /** 阅读关闭 */
    public static final String TYPE_READ_CLOSED = "-6";
    /** 无网络 */
    public static final String TYPE_NO_NET = "-7";
    /** 书豆不足 */
    private static final String TYPE_BOOK_BEAN_INSUFFICIENT = "2";
    /** 书籍已下架 */
    public static final String TYPE_BOOK_SOLD_OUT = "9";
    /** 获取目录失败 */
    public static final String TYPE_GET_CATALOG_FAIL = "-2";
    /** 按章免费 */

    public static final int EXCEPTION_HANDLING_RESID_DEFAULT = -1;
    private static final String TAG = "BookContentUtils";

    public static BookContentParserBase getBookContentParse(int type) {
        switch (type) {
            case Constant.BOOKTYPE_TXT:
                return new BookContentLocalAppTXTParser();
            case Constant.BOOKTYPE_PAY:
                return new BookContentPayBookParser();
            case Constant.BOOKTYPE_NET:
                return new BookContentPayBookParser();
            case Constant.BOOKTYPE_BAG:
                return new BookContentLocalAppBagParser();
            case Constant.BOOKTYPE_EPUB:
                return new BookContentLocalAppEPUBParser();
            case Constant.BOOKTYPE_UMD:
                return new BookContentLocalAppUMDParser();
            case Constant.BOOKTYPE_ORDER_PAY:
                return new BookContentPayBookParser();

            default:
                throw new IllegalArgumentException("Error book content parser type(Type = " + type
                        + ")!");
        }
    }

    public static void resetBookContentModelReadState(BookContentModel model, int type,
            boolean isNeedBuy, String curChapterType, String chapterName) {

        if (TYPE_DOWN_FAIL.equals(curChapterType)) {
            model.setTypeDonwload(chapterName, 6);
        } else if (TYPE_NO_NET.equals(curChapterType)) {
            model.setTypeDonwload(chapterName, 1);
        } else if (TYPE_GET_CATALOG_FAIL.equals(curChapterType)) {
            model.setTypeDonwload(chapterName, 5);
        } else {
            switch (type) {
                case Constant.BOOKTYPE_NET:
                    model.mReadState = BookContentModel.READ_STATE_NORMAL;
                    break;
                case Constant.BOOKTYPE_ORDER_PAY:
                    model.mReadState = BookContentModel.READ_STATE_PAY;
                    break;
                case Constant.BOOKTYPE_PAY:
                    model.mReadState = BookContentModel.READ_STATE_NORMAL;
                    break;
                default:
                    model.mReadState = BookContentModel.READ_STATE_NORMAL;
                    break;
            }
        }
    }

    /**
     * 处理阅读关闭异常
     * 
     * @param strType 异常类型
     */
    public static int exceptionHandling(String strType) {

        int resId = EXCEPTION_HANDLING_RESID_DEFAULT;

        if (TYPE_BOOK_CLOSED.equals(strType)) {// 书籍关闭
            resId = R.string.book_close;
        } else if (TYPE_READ_CLOSED.equals(strType)) {// 阅读关闭
            resId = R.string.bookcontent_close;
            // } else if (TYPE_DOWN_FAIL.equals(strType)) {// 下载失败
            // resId = R.string.bookcontent_down_fail;
        } else if (TYPE_BOOK_BEAN_INSUFFICIENT.equals(strType)) {// 书都不足
            resId = R.string.bookcontent_bean_insufficient;
        } else if (TYPE_BOOK_SOLD_OUT.equals(strType)) {// 书籍已下架
            resId = R.string.bookcontent_sold_out;
        }/*
          * else if (TYPE_GET_CATALOG_FAIL.equals(strType)) {// 获取目录失败 resId =
          * R.string.bookcontent_no_net;// bookcontent_get_catalog_fail }
          *//*
             * else if (TYPE_NO_NET.equals(strType)) {// 网络连接失败 resId = R.string.bookcontent_no_net;
             * }
             */else {
            if (TextUtils.isEmpty(strType)) {
                resId = R.string.getchapter_fail;
            }
        }

        return resId;
    }

    /***
     * 
     * @param curChapterId
     * @param totalLength
     * @return
     */
    public static float getChapterPercent(int curChapterId, int chapterSize) {
        return chapterSize == 0 ? 0 : ((curChapterId + 1) / (float) chapterSize);
    }

    /***
     * 
     * 获取当前页面的百分比
     * 
     * 
     * @param isNext 是否为下一页
     * @param curLines 当前页面的行数
     * @param curChapter 当前
     * @param lineIndex 当前的行数其实位置
     * @param linesNum 行数
     * @return
     */
    public static float getLocalFilePercent(boolean isNext, BookContentInfo info) {
        float per = 0.00f;

        if (info != null && info.getCurChapterContentLines() != null && info.getTotalLength() > 0) {
            final List<BookContentLineInfo> curLines = info.getCurChapterContentLines();

            final int lineIndex = info.getCurChapterLineIndex();
            final int linesNum = info.getCurSreenLineCount();
            final int totalLength = info.getTotalLength();
            final int type = info.getType();

            if (isNext) {
                if ((lineIndex + linesNum) < curLines.size()) {
                    if (curLines.get(lineIndex + linesNum) != null) {
                        per =
                                getLineEndIndex(type, curLines, lineIndex + linesNum) * 100f
                                        / totalLength;
                    }
                } else {
                    if (curLines.size() > 1 && curLines.get((curLines.size() - 1)) != null) {
                        per =
                                getLineEndIndex(type, curLines, curLines.size() - 1) * 100f
                                        / totalLength;
                    }
                }
            } else {
                if (lineIndex >= linesNum) {
                    if (lineIndex + linesNum < curLines.size()) {
                        if (curLines.get(lineIndex + linesNum) != null) {
                            per =
                                    getLineEndIndex(type, curLines, lineIndex + linesNum) * 100f
                                            / totalLength;
                        }
                    } else {
                        if (curLines.size() > 0 && curLines.get((curLines.size() - 1)) != null) {
                            per =
                                    getLineEndIndex(type, curLines, curLines.size() - 1) * 100f
                                            / totalLength;
                        }
                    }
                } else {
                    if (curLines.size() > lineIndex && curLines.get(lineIndex) != null) {
                        per = getLineEndIndex(type, curLines, lineIndex) * 100f / totalLength;
                    }
                }
            }

        }
        return per;
    }

    private static int getLineEndIndex(int type, List<BookContentLineInfo> curLines, int lineIndex) {
        int endIndex = curLines.get(lineIndex).getEndIndex();

        return type == Constant.BOOKTYPE_UMD ? endIndex / 2 : endIndex;
    }

    /***
     * 
     * 转换为书签的model
     * 
     * @param bookContentInfo
     * @param bookInfo
     */
    private static BookMarkInfo convertToBookMarkInfo(final BookContentInfo bookContentInfo,
            BookInfo bookInfo) {

        if (bookContentInfo == null) {
            return null;
        }


        BookMarkInfo markInfo = new BookMarkInfo();
        switch (bookContentInfo.getType()) {
            case Constant.BOOKTYPE_PAY:
                markInfo.setBookType(bookContentInfo.isOld() ? BookMarkInfo.TYPE_OLD_ONLINE_BOOKMARK
                        : BookMarkInfo.TYPE_NEW_PAY_BOOKMARK);
                break;
            case Constant.BOOKTYPE_ORDER_PAY:
                markInfo.setBookType(BookMarkInfo.TYPE_NEW_PAY_BOOKMARK);
                break;
            case Constant.BOOKTYPE_NET:
                markInfo.setBookType(BookMarkInfo.TYPE_NEW_SHENMA_BOOKMARK);
                break;
            case Constant.BOOKTYPE_TXT:
                markInfo.setBookType(BookMarkInfo.TYPE_LOCAL_BOOKMARK);
                markInfo.setChapterName("本地书签");
                break;
            case Constant.BOOKTYPE_UMD:
                final String umdChapterName =
                        !TextUtils.isEmpty(bookContentInfo.getCurChapterName()) ? bookContentInfo
                                .getCurChapterName() : "本地书签";
                markInfo.setChapterName(umdChapterName);
                markInfo.setBookType(BookMarkInfo.TYPE_LOCAL_BOOKMARK);
                break;
            case Constant.BOOKTYPE_EPUB:
                final String epubChapterName =
                        !TextUtils.isEmpty(bookContentInfo.getCurChapterName()) ? bookContentInfo
                                .getCurChapterName() : "本地书签";
                markInfo.setChapterName(epubChapterName);
                markInfo.setBookType(BookMarkInfo.TYPE_LOCAL_BOOKMARK);
                break;
            case Constant.BOOKTYPE_BAG:
                markInfo.setBookType(BookMarkInfo.TYPE_OLD_BAG_BOOKMARK);
                break;
        }

        if (bookInfo == null) {
            bookInfo = new BookInfo();
        }

        BookMarkInfo tmpMarkInfo =
                BookMarkInfoDao.getInstance().getBookMark(bookContentInfo.getSourceId(),
                        bookContentInfo.getBookId(), bookContentInfo.getUid(),
                        markInfo.getBookType());
        if (tmpMarkInfo != null && tmpMarkInfo.getTotalChapter() > bookInfo.getBookMaxOid()) {
            bookInfo.setBookMaxOid(tmpMarkInfo.getTotalChapter());
        }

        Log4an.e(
                "yjd",
                "【保存书签】name：" + bookContentInfo.getBookname() + ",bid="
                        + bookContentInfo.getBookId() + ",readByte="
                        + bookContentInfo.getBookmarkByteOffset() + ",type="
                        + bookContentInfo.getType() + ",cid=" + bookContentInfo.getCurChapterCid());

        markInfo.setBookName(bookContentInfo.getBookname());
        markInfo.setSourceId(bookContentInfo.getSourceId());
        markInfo.setBookId(bookContentInfo.getBookId());
        markInfo.setChapterId(bookContentInfo.getCurChapterCid());//
        markInfo.setBookReadByte(bookContentInfo.getBookmarkByteOffset());
        markInfo.setBookTotalByte(bookContentInfo.getTotalLength());
        markInfo.setChapterName(bookContentInfo.getCurChapterName());
        markInfo.setPayMode(bookContentInfo.getCurChapterPayMode());
        markInfo.setUserId(bookContentInfo.getUid());
        markInfo.setBookCoverImgUrl(TextUtils.isEmpty(bookInfo.getBookCoverImgUrl()) ? bookContentInfo
                .getImageUrl() : bookInfo.getBookCoverImgUrl());
        markInfo.setTotalChapter(bookInfo.getBookMaxOid());
        int tmpType = bookContentInfo.getType();
        /*
         * 解决本地书签保存的进度是0.xxxxx,而网络书签都是xx.xxxx
         */
        if (Constant.BOOKTYPE_TXT == tmpType || Constant.BOOKTYPE_UMD == tmpType
                || Constant.BOOKTYPE_EPUB == tmpType || Constant.BOOKTYPE_BAG == tmpType) {
            // 容错处理
            try {
                float percent = Float.valueOf(bookContentInfo.getPercent1());
                if (percent <= 1.0) {
                    percent = percent * 100;
                }
                markInfo.setPercent(percent);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            markInfo.setPercent(bookContentInfo.getPercent1());
        }
        markInfo.setFilePath(bookContentInfo.getFliePath());
        markInfo.setUpdateFlag(BookMarkInfo.UPDATE_FLAG_NOT);


        return markInfo;
    }

    /***
     * 保存书签
     * 
     * @param runOnUiThread 是否在主线程执行
     */
    public static void saveBookMark(final BookContentInfo bookContentInfo) {

        BookInfo bookInfo =
                BookInfoDao.getInstance().getBookInfo(bookContentInfo.getSourceId(),
                        bookContentInfo.getBookId(), bookContentInfo.getUid());

        BookMarkInfo markInfo = convertToBookMarkInfo(bookContentInfo, bookInfo);
        // Log.d(TAG, "saveBookMark markInfo == NULL ? " + (markInfo == null));

        if (markInfo != null) {

            // Log.d(TAG, "saveBookMark markInfo.getBookReadByte() ? " + markInfo.getBookReadByte()
            // + "  " + markInfo.getBookName());

            BookMarkInfoDao.getInstance().updateBookMark(markInfo);
        }
    }

    /**
     * 当用户阅读的书籍有书签信息时计算该书签在当前章节中的行号，保存书签时的行号和重新计算的行号有可能不同，因为在保存该书签后用户可能调整了阅读页的字号等设置。
     * 
     * @param info 需要重新计算书签行号的BookContentInfo
     */
    public static void calcBookmarkLineIndex(BookContentInfo info) {
        if (!info.getCurChapter().isValid() || info.getBookmarkByteOffset() <= 0)
            return;
        List<BookContentLineInfo> lines = info.getCurChapterContentLines();
        final int bookmarkOffset = info.getBookmarkByteOffset();
        info.setMarkIndex(bookmarkOffset);
        Log4an.e("yyy", "[calcBookmarkLineIndex]bookmarkOffset=" + bookmarkOffset);
        final int size = lines.size();
        for (int i = 0; i < size; i++) {
            BookContentLineInfo line = lines.get(i);
            if (line.getFirstIndex() <= bookmarkOffset && line.getEndIndex() >= bookmarkOffset) {
                info.setCurChapterLineIndex(i / info.getCurSreenLineCount()
                        * info.getCurSreenLineCount());
                break;
            }

        }
    }

    /**
     * 当用户改变了字体大小等设置后重新计算应该显示的行号。
     * 
     * @param info 需要重新计算行号的BookContentInfo
     */
    public static void calcPageLineIndex(BookContentInfo info, int originalFirstLineStartIndex) {
        if (!info.getCurChapter().isValid() || originalFirstLineStartIndex < 0)
            return;
        List<BookContentLineInfo> lines = info.getCurChapterContentLines();
        final int size = lines.size();
        for (int i = 0; i < size; i++) {
            BookContentLineInfo line = lines.get(i);
            if (line.getFirstIndex() <= originalFirstLineStartIndex
                    && line.getEndIndex() >= originalFirstLineStartIndex) {
                info.setCurChapterLineIndex(i / info.getCurSreenLineCount()
                        * info.getCurSreenLineCount());
                break;
            }
        }
    }

    /**
     * 计算Txt,UMD格式本地书籍在跳转到上一个章节时读取数据的索引值
     * 
     * @param bookContentInfo 需要计算章节起始字节索引的BookContentInfo
     * @param lineInfo 当前页面一个字的字节索引值
     * @param catalogList 章节目录
     */
    public static void calcLocalBookPrevChapterStartIndex(BookContentInfo bookContentInfo,
            BookContentLineInfo lineInfo, List<BookContentInfo> catalogList) {
        int keyIndex = lineInfo.getFirstIndex() - 1;
        if (keyIndex < 0) {
            keyIndex = 0;
        }
        for (int i = 1; i < catalogList.size(); i++) {
            if ((i == catalogList.size() - 1 && lineInfo.getFirstIndex() >= catalogList.get(i)
                    .getStartIndex())
                    || (lineInfo.getFirstIndex() >= catalogList.get(i).getStartIndex() && lineInfo
                            .getFirstIndex() < catalogList.get(i + 1).getStartIndex())) {
                keyIndex = catalogList.get(i - 1).getStartIndex();
                if (keyIndex >= bookContentInfo.getTotalLength() - 1) {
                    keyIndex = bookContentInfo.getTotalLength() - 2;
                }
                bookContentInfo.setStartIndex(keyIndex);
                break;
            }
        }
    }

    /**
     * 计算Txt,UMD格式本地书籍在跳转到下一个章节时读取数据的索引值
     * 
     * @param bookContentInfo 需要计算章节起始字节索引的BookContentInfo
     * @param lineInfo 当前页面一个字的字节索引值
     * @param catalogList 章节目录
     */
    public static void calcLocalBookNextChapterStartIndex(BookContentInfo bookContentInfo,
            BookContentLineInfo lineInfo, List<BookContentInfo> catalogList) {
        int keyIndex = lineInfo.getFirstIndex();
        if (keyIndex < 0) {
            keyIndex = 0;
        }
        for (int i = 0; i < catalogList.size() - 1; i++) {
            if ((keyIndex == 0 || keyIndex >= catalogList.get(i).getStartIndex())
                    && keyIndex < catalogList.get(i + 1).getStartIndex()) {
                keyIndex = catalogList.get(i + 1).getStartIndex();
                if (keyIndex >= bookContentInfo.getTotalLength() - 1) {
                    keyIndex = bookContentInfo.getTotalLength() - 2;
                }
                break;
            }
        }
        bookContentInfo.setStartIndex(keyIndex);
    }

    /***
     * 判断BookContentInfo中的curChapter是否需要购买
     * 
     * @param context
     * @param paramBookContentInfo
     * @return
     */
    public static boolean getIsNeedBuy(Context context, BookContentInfo paramBookContentInfo) {
        return getIsNeedBuy(context, paramBookContentInfo, null, null);
    }

    /***
     * 判断BookContentInfo中的curChapter是否需要购买
     * 
     * @param context
     * @param paramBookContentInfo
     * @return
     */
    public static boolean getIsNeedBuy(Context context, BookContentInfo paramBookContentInfo,
            String chapterId, String chapterPayMode) {

        if (paramBookContentInfo == null
                || (paramBookContentInfo.getType() != Constant.BOOKTYPE_PAY && paramBookContentInfo
                        .getType() != Constant.BOOKTYPE_ORDER_PAY)) {
            return false;
        }

        BookCataLog cataLogInfo =
                BookCataLogDao.getInstance().getBookCatalogByCid(paramBookContentInfo.getUid(),
                        paramBookContentInfo.getBookId(), paramBookContentInfo.getSourceId(),
                        chapterId == null ? paramBookContentInfo.getCurChapterCid() : chapterId);

        if (cataLogInfo == null) {
            return false;
        }

        final int oid = cataLogInfo.getOId();

        int pageSize = 3;
        int startOid = oid - 1;// 从上一章开始获取
        if (startOid <= 0) {// 无上一章
            startOid = 1;
            pageSize = 2;
        }

        List<BookCataLog> cataLogList =
                BookCataLogDao.getInstance().getBookCatalogListFromChapterIndex(
                        paramBookContentInfo.getUid(), paramBookContentInfo.getBookId(),
                        paramBookContentInfo.getSourceId(), startOid, pageSize + 4);

        int curChapterPayId = 0;
        for (int i = 0; i < cataLogList.size() && i < pageSize; i++) {
            BookCataLog catalogInfo = cataLogList.get(i);
            if (oid == catalogInfo.getOId()) {// 当前章
                curChapterPayId = catalogInfo.getPayState();
                break;
            }
        }

        if (String.valueOf(BookInfo.FREE).equals(
                chapterPayMode == null ? paramBookContentInfo.getCurChapterPayMode()
                        : chapterPayMode)// 免费的
                || String.valueOf(BookInfo.ALL_BOOK_FREE).equals(
                        chapterPayMode == null ? paramBookContentInfo.getCurChapterPayMode()
                                : chapterPayMode)// 全本免费的章节
                || String.valueOf(BookInfo.HAS_PAY).equals(curChapterPayId)
                || curChapterPayId == BookCataLog.HAS_PAY) {// 已付费的
        } else {
            return paramBookContentInfo.isNeedBuy();
        }
        return false;
    }
}
